package com.xy.wsl.api.authorize;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xy.wsl.api.response.AuthorizeException;
import com.xy.wsl.api.sql.entity.User.User;
import com.xy.wsl.api.sql.services.User.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.lang.reflect.Method;

@Component
@SuppressWarnings("all")
public class JWTInterceptor implements HandlerInterceptor {
    @Autowired
    UserService user;
    // 请求前到达之前拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object)
            throws Exception {
        // 从请求头获取 token
        String token = request.getHeader("Authorization");
        //首先映射是不是方法，如果不是则返回
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod) object;
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释，有则跳过认证
//        if (method.isAnnotationPresent(PassToken.class)) {
//            PassToken passToken = method.getAnnotation(PassToken.class);
//            if (passToken.required()) {
//                return true;
//            }
//        }

        // token 验证失败后的返回信息
        if (method.isAnnotationPresent(Authorize.class)) {
            Authorize userLoginToken = method.getAnnotation(Authorize.class);
            if (userLoginToken.required()) {
                if (token == null || token.isEmpty()) {
                    throw new AuthorizeException( "无token，请重新登录");
                }
                // 获取 token 中的 user id
                String uid;
                try {
                    DecodedJWT decode = JWT.decode(token.replace("Bearer ",""));
                    uid = decode.getClaim("uid").asString();
                } catch (JWTDecodeException j) {
                    throw new AuthorizeException("401");
                }

                User users = user.getWithKey(uid);
                if (users == null) {
                    throw new AuthorizeException("用户不存在，请重新登录");
                }
                Algorithm algorithm = Algorithm.HMAC256(users.getPassword());
                JWTVerifier jwtVerifier = JWT.require(algorithm).withClaim("name", users.getName())
                        .withClaim("uid",uid).build();
                try {
                    // JWT 工具包验证 token
                    jwtVerifier.verify(token.replace("Bearer ",""));
                    return true;
                } catch (TokenExpiredException e) {
                    throw new AuthorizeException("Token已经过期!!!");
                } catch (SignatureVerificationException e){
                    throw new AuthorizeException("签名错误!!!");
                } catch (AlgorithmMismatchException e){
                    throw new AuthorizeException("加密算法不匹配!!!");
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new AuthorizeException("无效token~~");
                }
            }
        }
        return true;
    }
}
